﻿// -----------------------------------------------------------------------
//  Copyright (c) 2011, The Outercurve Foundation.  
//  This software is released under the Apache License, Version 2.0. 
//  The license and further copyright text can be found in the file LICENSE.TXT at
//  the root directory of the distribution.
// -----------------------------------------------------------------------
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;

namespace Chem4Word.UI.UIControls
{
    public enum SearchMode
    {
        Instant,
        Delayed,
    }

    public class SearchTextBox : TextBox
    {
//        public static readonly RoutedEvent SearchEvent =
//            EventManager.RegisterRoutedEvent(
//                "Search",
//                RoutingStrategy.Bubble,
//                typeof (RoutedEventHandler),
//                typeof (SearchTextBox));

//        public static DependencyProperty HasTextProperty = HasTextPropertyKey.DependencyProperty;

//        private static DependencyPropertyKey HasTextPropertyKey =
//            DependencyProperty.RegisterReadOnly(
//                "HasText",
//                typeof (bool),
//                typeof (SearchTextBox),
//                new PropertyMetadata());

//        public static DependencyProperty IsMouseLeftButtonDownProperty =
//            IsMouseLeftButtonDownPropertyKey.DependencyProperty;

//        private static DependencyPropertyKey IsMouseLeftButtonDownPropertyKey =
//            DependencyProperty.RegisterReadOnly(
//                "IsMouseLeftButtonDown",
//                typeof (bool),
//                typeof (SearchTextBox),
//                new PropertyMetadata());

//        public static DependencyProperty LabelTextColorProperty =
//            DependencyProperty.Register(
//                "LabelTextColor",
//                typeof (Brush),
//                typeof (SearchTextBox));

//        public static DependencyProperty LabelTextProperty =
//            DependencyProperty.Register(
//                "LabelText",
//                typeof (string),
//                typeof (SearchTextBox));

//        public static DependencyProperty SearchEventTimeDelayProperty =
//            DependencyProperty.Register(
//                "SearchEventTimeDelay",
//                typeof (Duration),
//                typeof (SearchTextBox),
//                new FrameworkPropertyMetadata(
//                    new Duration(new TimeSpan(0, 0, 0, 0, 500)),
//                    new PropertyChangedCallback(OnSearchEventTimeDelayChanged)));

//        public static DependencyProperty SearchModeProperty =
//            DependencyProperty.Register(
//                "SearchMode",
//                typeof (SearchMode),
//                typeof (SearchTextBox),
//                new PropertyMetadata(SearchMode.Instant));

//        private DispatcherTimer searchEventDelayTimer;

//        static SearchTextBox()
//        {
//            DefaultStyleKeyProperty.OverrideMetadata(
//                typeof (SearchTextBox),
//                new FrameworkPropertyMetadata(typeof (SearchTextBox)));
//        }

//        public SearchTextBox()
//        {
//            searchEventDelayTimer = new DispatcherTimer {Interval = SearchEventTimeDelay.TimeSpan};
//            searchEventDelayTimer.Tick += OnSeachEventDelayTimerTick;
//        }

//        public string LabelText
//        {
//            get { return (string) GetValue(LabelTextProperty); }
//            set { SetValue(LabelTextProperty, value); }
//        }

//        public Brush LabelTextColor
//        {
//            get { return (Brush) GetValue(LabelTextColorProperty); }
//            set { SetValue(LabelTextColorProperty, value); }
//        }

//        public SearchMode SearchMode
//        {
//            get { return (SearchMode) GetValue(SearchModeProperty); }
//            set { SetValue(SearchModeProperty, value); }
//        }

//        public bool HasText
//        {
//            get { return (bool) GetValue(HasTextProperty); }
//            private set { SetValue(HasTextPropertyKey, value); }
//        }

//        public Duration SearchEventTimeDelay
//        {
//            get { return (Duration) GetValue(SearchEventTimeDelayProperty); }
//            set { SetValue(SearchEventTimeDelayProperty, value); }
//        }

//        public bool IsMouseLeftButtonDown
//        {
//            get { return (bool) GetValue(IsMouseLeftButtonDownProperty); }
//            private set { SetValue(IsMouseLeftButtonDownPropertyKey, value); }
//        }

//        private void OnSeachEventDelayTimerTick(object o, EventArgs e)
//        {
//            searchEventDelayTimer.Stop();
//            RaiseSearchEvent();
//        }

//        private static void OnSearchEventTimeDelayChanged(
//            DependencyObject o, DependencyPropertyChangedEventArgs e)
//        {
//            SearchTextBox stb = o as SearchTextBox;
//            if (stb != null)
//            {
//                stb.searchEventDelayTimer.Interval = ((Duration) e.NewValue).TimeSpan;
//                stb.searchEventDelayTimer.Stop();
//            }
//        }

//        protected override void OnTextChanged(TextChangedEventArgs e)
//        {
//            base.OnTextChanged(e);

//            HasText = Text.Length != 0;

//            if (SearchMode == SearchMode.Instant)
//            {
//                searchEventDelayTimer.Stop();
//                searchEventDelayTimer.Start();
//            }
//        }

//        public override void OnApplyTemplate()
//        {
//            base.OnApplyTemplate();

//            Border iconBorder = GetTemplateChild("PART_SearchIconBorder") as Border;
//            if (iconBorder != null)
//            {
//                iconBorder.MouseLeftButtonDown += IconBorderMouseLeftButtonDown;
//                iconBorder.MouseLeftButtonUp += IconBorderMouseLeftButtonUp;
//                iconBorder.MouseLeave += IconBorderMouseLeave;
//            }
//        }

//        private void IconBorderMouseLeftButtonDown(object obj, MouseButtonEventArgs e)
//        {
//            IsMouseLeftButtonDown = true;
//        }

//        private void IconBorderMouseLeftButtonUp(object obj, MouseButtonEventArgs e)
//        {
//            if (!IsMouseLeftButtonDown)
//            {
//                return;
//            }

//            if (HasText && SearchMode == SearchMode.Instant)
//            {
//                this.Text = "";
//            }

//            if (HasText && SearchMode == SearchMode.Delayed)
//            {
//                RaiseSearchEvent();
//            }

//            IsMouseLeftButtonDown = false;
//        }

//        private void IconBorderMouseLeave(object obj, MouseEventArgs e)
//        {
//            IsMouseLeftButtonDown = false;
//        }

//        protected override void OnKeyDown(KeyEventArgs e)
//        {
//            if (e.Key == Key.Escape && SearchMode == SearchMode.Instant)
//            {
//                this.Text = "";
//            }
//            else if ((e.Key == Key.Return || e.Key == Key.Enter) &&
//                     SearchMode == SearchMode.Delayed)
//            {
//                RaiseSearchEvent();
//            }
//            else
//            {
//                base.OnKeyDown(e);
//            }
//        }

//        private void RaiseSearchEvent()
//        {
//            RoutedEventArgs args = new RoutedEventArgs(SearchEvent);
//            RaiseEvent(args);
//        }

//        public event RoutedEventHandler Search
//        {
//            add { AddHandler(SearchEvent, value); }
//            remove { RemoveHandler(SearchEvent, value); }
//        }
//    }
//}

        public static DependencyProperty LabelTextProperty =
           DependencyProperty.Register(
               "LabelText",
               typeof(string),
               typeof(SearchTextBox));

        public static DependencyProperty LabelTextColorProperty =
            DependencyProperty.Register(
                "LabelTextColor",
                typeof(Brush),
                typeof(SearchTextBox));

        public static DependencyProperty SearchModeProperty =
            DependencyProperty.Register(
                "SearchMode",
                typeof(SearchMode),
                typeof(SearchTextBox),
                new PropertyMetadata(SearchMode.Instant));

        private static DependencyPropertyKey HasTextPropertyKey =
            DependencyProperty.RegisterReadOnly(
                "HasText",
                typeof(bool),
                typeof(SearchTextBox),
                new PropertyMetadata());
        public static DependencyProperty HasTextProperty = HasTextPropertyKey.DependencyProperty;




        private static DependencyPropertyKey IsMouseLeftButtonDownPropertyKey =
            DependencyProperty.RegisterReadOnly(
                "IsMouseLeftButtonDown",
                typeof(bool),
                typeof(SearchTextBox),
                new PropertyMetadata());
        public static DependencyProperty IsMouseLeftButtonDownProperty = IsMouseLeftButtonDownPropertyKey.DependencyProperty;












        public static DependencyProperty SearchEventTimeDelayProperty =
            DependencyProperty.Register(
                "SearchEventTimeDelay",
                typeof(Duration),
                typeof(SearchTextBox),
                new FrameworkPropertyMetadata(
                    new Duration(new TimeSpan(0, 0, 0, 0, 500)),
                    new PropertyChangedCallback(OnSearchEventTimeDelayChanged)));

        public static readonly RoutedEvent SearchEvent =
            EventManager.RegisterRoutedEvent(
                "Search",
                RoutingStrategy.Bubble,
                typeof(RoutedEventHandler),
                typeof(SearchTextBox));

        static SearchTextBox()
        {
            DefaultStyleKeyProperty.OverrideMetadata(
                typeof(SearchTextBox),
                new FrameworkPropertyMetadata(typeof(SearchTextBox)));
        }

        private DispatcherTimer searchEventDelayTimer;








        public SearchTextBox()
        {
            searchEventDelayTimer = new DispatcherTimer { Interval = SearchEventTimeDelay.TimeSpan };
            searchEventDelayTimer.Tick += OnSeachEventDelayTimerTick;
        }

        void OnSeachEventDelayTimerTick(object o, EventArgs e)
        {
            searchEventDelayTimer.Stop();
            RaiseSearchEvent();
        }

        static void OnSearchEventTimeDelayChanged(
            DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            SearchTextBox stb = o as SearchTextBox;
            if (stb != null)
            {
                stb.searchEventDelayTimer.Interval = ((Duration)e.NewValue).TimeSpan;
                stb.searchEventDelayTimer.Stop();
            }
        }

        protected override void OnTextChanged(TextChangedEventArgs e)
        {
            base.OnTextChanged(e);

            HasText = Text.Length != 0;

            if (SearchMode == SearchMode.Instant)
            {
                searchEventDelayTimer.Stop();
                searchEventDelayTimer.Start();
            }
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            Border iconBorder = GetTemplateChild("PART_SearchIconBorder") as Border;
            if (iconBorder != null)
            {
                iconBorder.MouseLeftButtonDown += new MouseButtonEventHandler(IconBorderMouseLeftButtonDown);
                iconBorder.MouseLeftButtonUp += new MouseButtonEventHandler(IconBorderMouseLeftButtonUp);
                iconBorder.MouseLeave += new MouseEventHandler(IconBorderMouseLeave);
            }
        }

        private void IconBorderMouseLeftButtonDown(object obj, MouseButtonEventArgs e)
        {
            IsMouseLeftButtonDown = true;
        }

        private void IconBorderMouseLeftButtonUp(object obj, MouseButtonEventArgs e)
        {
            if (!IsMouseLeftButtonDown) return;




            if (HasText && SearchMode == SearchMode.Instant)
            {
                this.Text = "";
            }

            if (HasText && SearchMode == SearchMode.Delayed)
            {
                RaiseSearchEvent();
            }

            IsMouseLeftButtonDown = false;
        }

        private void IconBorderMouseLeave(object obj, MouseEventArgs e)
        {
            IsMouseLeftButtonDown = false;
        }

        protected override void OnKeyDown(KeyEventArgs e)
        {
            if (e.Key == Key.Escape && SearchMode == SearchMode.Instant)
            {
                this.Text = "";
            }
            else if ((e.Key == Key.Return || e.Key == Key.Enter) &&
                SearchMode == SearchMode.Delayed)
            {
                RaiseSearchEvent();
            }
            else
            {
                base.OnKeyDown(e);
            }
        }

        private void RaiseSearchEvent()
        {
            RoutedEventArgs args = new RoutedEventArgs(SearchEvent);
            RaiseEvent(args);
        }

        public string LabelText
        {
            get { return (string)GetValue(LabelTextProperty); }
            set { SetValue(LabelTextProperty, value); }
        }

        public Brush LabelTextColor
        {
            get { return (Brush)GetValue(LabelTextColorProperty); }
            set { SetValue(LabelTextColorProperty, value); }
        }

        public SearchMode SearchMode
        {
            get { return (SearchMode)GetValue(SearchModeProperty); }
            set { SetValue(SearchModeProperty, value); }
        }

        public bool HasText
        {
            get { return (bool)GetValue(HasTextProperty); }
            private set { SetValue(HasTextPropertyKey, value); }
        }

        public Duration SearchEventTimeDelay
        {
            get { return (Duration)GetValue(SearchEventTimeDelayProperty); }
            set { SetValue(SearchEventTimeDelayProperty, value); }
        }

        public bool IsMouseLeftButtonDown
        {
            get { return (bool)GetValue(IsMouseLeftButtonDownProperty); }
            private set { SetValue(IsMouseLeftButtonDownPropertyKey, value); }
        }

        public event RoutedEventHandler Search
        {
            add { AddHandler(SearchEvent, value); }
            remove { RemoveHandler(SearchEvent, value); }
        }
    }
}

